#include "aodv_rerr.h"
#include <stdio.h>
#include <string.h>
#include <time.h>

/**
 * 构建RERR消息（带类型）
 */
void build_rerr_packet_with_type(aodv_rerr *rerr, uint32_t dest_addr, uint32_t dest_seq_num, rerr_type_t type) {
    if (!rerr) return;
    
    memset(rerr, 0, sizeof(aodv_rerr));
    rerr->header.type = AODV_RERR;
    rerr->dest_count = 1;  // 单个目的地址
    // 注意：aodv_types.h中的aodv_rerr结构体包含dest_count字段，
    // 但不包含直接的dest_addr和dest_seq_num字段
    // 这里我们简化处理，假设只有一个不可达目的地
}

/**
 * 验证RERR消息的有效性
 */
int validate_rerr_message(const aodv_rerr *rerr) {
    if (!rerr) return 0;
    
    // 检查消息类型
    if (rerr->header.type != AODV_RERR) {
        printf("Invalid RERR message type: %d\n", rerr->header.type);
        return 0;
    }
    
    // 检查目的地址数量
    if (rerr->dest_count == 0) {
        printf("Invalid RERR destination count: 0\n");
        return 0;
    }
    
    return 1;
}

/**
 * 处理接收到的RERR消息
 */
int process_rerr_message(const aodv_rerr *rerr, uint32_t sender_addr, 
                        aodv_routing_table *routing_table, uint32_t local_ip) {
    if (!rerr || !routing_table) return 0;
    
    printf("Processing RERR from %s\n", 
           inet_ntoa(*(struct in_addr*)&sender_addr));
    
    // 验证RERR消息
    if (!validate_rerr_message(rerr)) {
        printf("Invalid RERR message received from %s\n", 
               inet_ntoa(*(struct in_addr*)&sender_addr));
        return 0;
    }
    
    // 简化处理：假设只有一个不可达目的地
    // 在实际实现中，这里需要解析变长数组中的多个不可达目的地
    printf("RERR message contains %d unreachable destinations\n", rerr->dest_count);
    
    return 1;
}

/**
 * 转发RERR消息
 */
int forward_rerr_message(const aodv_rerr *rerr, SOCKET socket, 
                        aodv_routing_table *routing_table, uint32_t local_ip) {
    if (!rerr || !routing_table) return 0;
    
    // 查找所有使用相同下一跳的路由条目
    int forwarded_count = 0;
    
    for (int i = 0; i < routing_table->count; i++) {
        routing_table_entry *entry = &routing_table->entries[i];
        
        // 如果这是使用相同下一跳的有效路由，转发RERR
        if (routing_table_is_valid(routing_table, entry->dest_addr) && entry->next_hop_addr != local_ip) {
            struct sockaddr_in dest_addr;
            dest_addr.sin_family = AF_INET;
            dest_addr.sin_port = htons(AODV_PORT);
            dest_addr.sin_addr.s_addr = entry->next_hop_addr;
            
            // 发送RERR消息
            int result = sendto(socket, (const char*)rerr, sizeof(aodv_rerr), 0,
                               (struct sockaddr*)&dest_addr, sizeof(dest_addr));
            
            if (result != SOCKET_ERROR) {
                printf("Forwarded RERR to %s\n",
                       inet_ntoa(*(struct in_addr*)&entry->next_hop_addr));
                forwarded_count++;
            } else {
                printf("Failed to forward RERR to %s\n",
                       inet_ntoa(*(struct in_addr*)&entry->next_hop_addr));
            }
        }
    }
    
    return forwarded_count > 0 ? 1 : 0;
}

/**
 * 发送RERR消息
 */
int send_rerr_message(uint32_t dest_addr, uint32_t dest_seq_num, 
                     SOCKET socket, aodv_routing_table *routing_table, uint32_t local_ip) {
    if (!routing_table) return 0;
    
    aodv_rerr rerr;
    build_rerr_packet_with_type(&rerr, dest_addr, dest_seq_num, RERR_DEST_UNREACHABLE);
    
    printf("Sending RERR for destination %s (seq_num=%u)\n",
           inet_ntoa(*(struct in_addr*)&dest_addr), dest_seq_num);
    
    // 转发RERR消息到相关邻居
    return forward_rerr_message(&rerr, socket, routing_table, local_ip);
}

/**
 * 处理路由错误（链路故障）
 */
int handle_route_error(uint32_t broken_link_addr, SOCKET socket, 
                      aodv_routing_table *routing_table, uint32_t local_ip) {
    if (!routing_table) return 0;
    
    printf("Handling route error for broken link to %s\n",
           inet_ntoa(*(struct in_addr*)&broken_link_addr));
    
    int affected_count = 0;
    
    // 查找所有通过该链路的路由条目
    for (int i = 0; i < routing_table->count; i++) {
        routing_table_entry *entry = &routing_table->entries[i];
        
        if (entry->next_hop_addr == broken_link_addr && routing_table_is_valid(routing_table, entry->dest_addr)) {
            printf("Found affected route to %s via broken link %s\n",
                   inet_ntoa(*(struct in_addr*)&entry->dest_addr),
                   inet_ntoa(*(struct in_addr*)&broken_link_addr));
            
            // 增加序列号并标记为无效
            entry->dest_seq_num++;
            entry->lifetime = (uint32_t)time(NULL) - 1;
            
            // 发送RERR消息
            if (send_rerr_message(entry->dest_addr, entry->dest_seq_num, 
                                  socket, routing_table, local_ip)) {
                affected_count++;
            }
        }
    }
    
    printf("Route error handling completed, affected %d routes\n", affected_count);
    return affected_count;
}